package com.sample;


import com.itext.sample.util.PdfUtils;
import com.itextpdf.text.Element;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.*;
import org.docx4j.Docx4J;
import org.docx4j.convert.out.FOSettings;
import org.docx4j.fonts.IdentityPlusMapper;
import org.docx4j.fonts.Mapper;
import org.docx4j.fonts.PhysicalFonts;
import org.docx4j.model.datastorage.migration.VariablePrepare;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;
import org.springframework.util.StopWatch;

import javax.swing.*;
import java.awt.*;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.*;

public class DocAndPdfSample {

    // 间隔
    public final static int interval = -new Random().nextInt(20) * 7;

    // 目录和文件
    public final static String ROOT_DIR = "d:/temp/",
            TEMP_DOCX = ROOT_DIR + "template.docx",
            SEAL_PNG = ROOT_DIR + "seal.png",
            TRANS_PDF = ROOT_DIR + "temp" + interval + ".pdf",
            WATER_MARK_PDF = ROOT_DIR + "watermark" + interval + ".pdf",
            SEAL_PDF = ROOT_DIR + "seal" + interval + ".pdf";

    // 测试数据准备
    public final static Map<String, String> variables = new HashMap<String, String>() {{
        put("farmInfo.houseHoldName", "罗布");
        put("requestTypeLabel", "特困救助");
        put("reasonLabels", "十分富裕，全村希望");
        put("appdate", "2021年4月17日");
        put("now_date", "2021年4月23日");
    }};

    public final static Set<String> KEY_WORDS = new HashSet<String>() {{
        add("签章甲");
        add("签章乙");
    }};

    public static void main(String[] args) throws Exception {
        // 工程名字在最后面统计信息中会打印出来
        StopWatch stopWatch = new StopWatch("DOC模板填制转PDF再盖章加水印 : " + interval);

        // 1. DOC填充并转PDF
        stopWatch.start("(1)DOC填充并转PDF");
        doc2pdf();
        stopWatch.stop();


        // 2. PDF签章
        stopWatch.start("(2)PDF签章");
        PdfUtils.stampImage(TRANS_PDF, SEAL_PDF, SEAL_PNG, KEY_WORDS);
        stopWatch.stop();

        // 3. PDF加水印
        stopWatch.start("(3)PDF加水印");
        setWatermark();
        stopWatch.stop();

        //打印一份格式化好的汇总统计信息
        System.out.println(stopWatch.prettyPrint());
    }


    private static void doc2pdf() throws Exception {
        //加载模板
        WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(new java.io.File(TEMP_DOCX));

        //进行数据合并
        MainDocumentPart documentPart = wordMLPackage.getMainDocumentPart();
        //数据替换预处理，调用API包
        //在表格替换后调用这个方法
        VariablePrepare.prepare(wordMLPackage);
        documentPart.variableReplace(variables);
        // 初始化，拿到系统中所有字体
        PhysicalFonts.discoverPhysicalFonts();
        // Set up font mapper (optional)
        Mapper fontMapper = new IdentityPlusMapper();
        fontMapper.put("华文中宋", PhysicalFonts.get("STZhongsong"));
        wordMLPackage.setFontMapper(fontMapper);
        // FO exporter setup (required)
        // .. the FOSettings object
        FOSettings foSettings = Docx4J.createFOSettings();
        foSettings.setWmlPackage(wordMLPackage);
        OutputStream pdfOutput = new FileOutputStream(TRANS_PDF);
        Docx4J.toPDF(wordMLPackage, pdfOutput);
        pdfOutput.close();
    }

    public static void setWatermark() throws Exception {

        // 要输出的pdf文件
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(WATER_MARK_PDF)));

        PdfReader reader = new PdfReader(SEAL_PDF);
        PdfStamper stamper = new PdfStamper(reader, bos);

        // 获取总页数 +1, 下面从1开始遍历
        int total = reader.getNumberOfPages() + 1;
        BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);

        Date date = new Date();
        String strDateFormat = "yyyy-MM-dd HH:mm:ss";
        SimpleDateFormat sdf = new SimpleDateFormat(strDateFormat);
        String waterMarkName = sdf.format(date) + "生成";


        System.out.println("Random interval: " + interval);

        // 获取水印文字的高度和宽度
        int textH = 0, textW = 0;
        JLabel label = new JLabel();
        label.setText(waterMarkName);
        FontMetrics metrics = label.getFontMetrics(label.getFont());
        textH = metrics.getHeight();
        textW = metrics.stringWidth(label.getText());
        System.out.println("textH: " + textH);
        System.out.println("textW: " + textW);

        // 设置水印透明度
        PdfGState gs = new PdfGState();

        // 填充透明度
        gs.setFillOpacity(0.2f);
        // 边框透明度
        gs.setStrokeOpacity(0.4f);

        Rectangle pageSizeWithRotation = null;
        PdfContentByte content = null;
        // 遍历页码
        for (int i = 1; i < total; i++) {
            // 在内容上方加水印
            content = stamper.getOverContent(i);
            // 在内容下方加水印
            // content = stamper.getUnderContent(i);
            content.saveState();
            content.setGState(gs);

            // 设置字体和字体大小
            content.beginText();
            content.setFontAndSize(base, 12);

            // 获取每一页的高度、宽度
            pageSizeWithRotation = reader.getPageSizeWithRotation(i);
            float pageHeight = pageSizeWithRotation.getHeight();
            float pageWidth = pageSizeWithRotation.getWidth();

            int stepW = textW * 2,
                    stepH = textH * 5,
                    countW = Math.round(pageWidth / stepW),
                    countH = Math.round(pageHeight / stepH);
            float rotation = textW / textH;


            for (int indexH = 0; indexH < countH; indexH++) {
                float x = (interval + textW * indexH) % pageWidth,
                        y = interval + stepH * indexH;

                for (int indexW = 0; indexW < countW; indexW++) {
                    x = x + stepW * indexW;
                    if (x > pageWidth) {
                        x = pageWidth - x;
                    }
                    content.showTextAligned(Element.ALIGN_LEFT, waterMarkName, x, y, rotation);
                }
            }
            content.endText();
        }

        // 关流
        stamper.close();
        reader.close();
        bos.close();
    }


}
